#pragma once

#include "MShape.h"

#include "AIS_InteractiveObject.hxx"
#include "AIS_InteractiveContext.hxx"
#include "AIS_Point.hxx"
#include "AIS_Axis.hxx"
#include "AIS_Line.hxx"
#include "AIS_Circle.hxx"
#include "AIS_Plane.hxx"
#include "AIS_PlaneTrihedron.hxx"
#include "AIS_PointCloud.hxx"

#include "PrsDim_ParallelRelation.hxx"
#include "PrsDim_PerpendicularRelation.hxx"
#include "PrsDim_LengthDimension.hxx"

#include "StdPrs_ShadedShape.hxx"
#include "StdPrs_WFShape.hxx"
#include "StdPrs_ToolTriangulatedShape.hxx"
#include "StdPrs_HLRPolyShape.hxx"

#include "Prs3d_ShadingAspect.hxx"
#include "Prs3d_ArrowAspect.hxx"
#include "Prs3d_Arrow.hxx"
#include "Prs3d_BndBox.hxx"
#include "Prs3d_ToolCylinder.hxx"
#include "Prs3d_ToolDisk.hxx"
#include "Prs3d_PresentationShadow.hxx"

#include "Graphic3d_ArrayOfPoints.hxx"
#include "Graphic3d_Text.hxx"

#include "SelectMgr_EntityOwner.hxx"
#include "Select3D_SensitivePrimitiveArray.hxx"
#include "Select3D_SensitivePoint.hxx"
#include "Select3D_SensitiveSegment.hxx"
#include "Select3D_SensitiveFace.hxx"
#include "Select3D_SensitiveBox.hxx"
#include "StdSelect_FaceFilter.hxx"
#include "StdSelect_ViewerSelector3d.hxx"
#include "StdSelect_BRepSelectionTool.hxx"

#include "Image_AlienPixMap.hxx"

// 添加边界线条
class MAisDemo : public AIS_InteractiveObject
{
	DEFINE_STANDARD_RTTI_INLINE(MAisDemo , AIS_InteractiveObject)
public:
	enum MDispMode {
		MDispMode_WireFrame ,
		MDispMode_Shaded
	};

	MAisDemo(const TopoDS_Shape& shap, bool indexVisible = false);

	virtual void Compute(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
						  const Handle(Prs3d_Presentation)& thePrs ,
						  const Standard_Integer theMode) override;

	virtual void ComputeSelection(const Handle(SelectMgr_Selection)& theSel ,
								   const Standard_Integer theMode) override;

	virtual bool AcceptDisplayMode(const Standard_Integer theMode) const override
	{
		return theMode == MDispMode_WireFrame || theMode == MDispMode_Shaded;
	}

	virtual void SetColor(const Quantity_Color& theColor) override;

	TopoDS_Shape Shape() const 
	{
		return myShape;
	}

	void setShape(TopoDS_Shape& theShape)
	{
		myShape = theShape;
	}

	void setFaceIndex(const Handle(Prs3d_Presentation)& thePrs);

	static TopAbs_ShapeEnum SelectionType(const Standard_Integer theSelMode)
	{
		switch (theSelMode)
		{
		case 1:
			return TopAbs_VERTEX;
		case 2:
			return TopAbs_EDGE;
		case 3:
			return TopAbs_WIRE;
		case 4:
			return TopAbs_FACE;
		case 5:
			return TopAbs_SHELL;
		case 6:
			return TopAbs_SOLID;
		case 7:
			return TopAbs_COMPSOLID;
		case 8:
			return TopAbs_COMPOUND;
		case 0:
			return TopAbs_SHAPE;
		}
		return TopAbs_SHAPE;
	}
	
	static Standard_Integer SelectionMode(const TopAbs_ShapeEnum theShapeType)
	{
		switch (theShapeType)
		{
		case TopAbs_VERTEX:
			return 1;
		case TopAbs_EDGE:
			return 2;
		case TopAbs_WIRE:
			return 3;
		case TopAbs_FACE:
			return 4;
		case TopAbs_SHELL:
			return 5;
		case TopAbs_SOLID:
			return 6;
		case TopAbs_COMPSOLID:
			return 7;
		case TopAbs_COMPOUND:
			return 8;
		case TopAbs_SHAPE:
			return 0;
		}
		return 0;
	}

private:
	TopoDS_Shape myShape;
	bool faceIndexIsVisible;
};

// None
class MAisObject : public AIS_InteractiveObject
{
	DEFINE_STANDARD_RTTI_INLINE(MAisObject , AIS_InteractiveObject)
public:
	enum MDispMode {
		MDispMode_WireFrame ,
		MDispMode_Shaded ,
		MDispMode_Shaded_HighLight ,
		MDispMode_Shaded_HighLightDynamic ,
		MDispMode_WireFrame_HighLight
	};

	MAisObject(std::shared_ptr< MSLinearRect> shap);

	virtual void Compute(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
						  const Handle(Prs3d_Presentation)& thePrs ,
						  const Standard_Integer theMode) override;

	virtual void ComputeSelection(const Handle(SelectMgr_Selection)& theSel ,
								   const Standard_Integer theMode) override;

	virtual bool AcceptDisplayMode(const Standard_Integer theMode) const override
	{
		return theMode == MDispMode_WireFrame || theMode == MDispMode_Shaded;
	}

	virtual void SetColor(const Quantity_Color& theColor) override;

	std::shared_ptr< MSLinearRect> Shape() const {
		return myShape;
	}

	void setShape(std::shared_ptr< MSLinearRect> theShape)
	{
		myShape = theShape;
	}

private:
	std::shared_ptr< MSLinearRect> myShape;
	Handle(Prs3d_Drawer) myShadeStyle;
	Handle(Prs3d_Drawer) myShadeStyleHighLight;
};

class MAisOwner : public SelectMgr_EntityOwner
{
	DEFINE_STANDARD_RTTI_INLINE(MAisOwner , SelectMgr_EntityOwner)
public:
	MAisOwner(const Handle(AIS_InteractiveObject)& theObj , int thePriority = 0)
		: SelectMgr_EntityOwner(theObj , thePriority) {
	}

	virtual void HilightWithColor(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
								   const Handle(Prs3d_Drawer)& theStyle ,
								   const Standard_Integer theMode) override;
	// 选择高亮对应的erase
	virtual void Unhilight(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
							const Standard_Integer theMode) override;

protected:
	Handle(Prs3d_Presentation) myPrsWire;
	Handle(Prs3d_Presentation) myPrs;
};

class MCaptureOwnerEndPonit : public SelectMgr_EntityOwner
{
	DEFINE_STANDARD_RTTI_INLINE(MCaptureOwnerEndPonit , SelectMgr_EntityOwner)
public:
	MCaptureOwnerEndPonit(gp_Pnt& pnt , const Handle(AIS_InteractiveObject)& theObj , int thePriority = 0);


	virtual void HilightWithColor(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
								   const Handle(Prs3d_Drawer)& theStyle ,
								   const Standard_Integer theMode) override;

	virtual void Unhilight(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
							const Standard_Integer theMode) override;

	gp_Pnt getPonit() const { return myPoint; }

protected:
	Handle(Prs3d_Presentation) myPrs;
	Handle(Prs3d_Presentation) myPrsDynamic;

	Handle(Prs3d_Drawer) myStyle;

	gp_Pnt myPoint;
};

class MCaptureOwnerMidPoint : public SelectMgr_EntityOwner
{
	DEFINE_STANDARD_RTTI_INLINE(MCaptureOwnerMidPoint , SelectMgr_EntityOwner)
public:
	MCaptureOwnerMidPoint(gp_Pnt& pnt , const Handle(AIS_InteractiveObject)& theObj , int thePriority = 0);

	virtual void HilightWithColor(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
								   const Handle(Prs3d_Drawer)& theStyle ,
								   const Standard_Integer theMode) override;

	virtual void Unhilight(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
							const Standard_Integer theMode) override;

	gp_Pnt getPonit() const { return myPoint; }

protected:
	Handle(Prs3d_Presentation) myPrs;
	Handle(Prs3d_Presentation) myPrsDynamic;
	Handle(Graphic3d_MarkerImage) img;
	Handle(Prs3d_Drawer) myStyle;
	gp_Pnt myPoint;
};

class MCaptureOwnerEdge : public SelectMgr_EntityOwner
{
	DEFINE_STANDARD_RTTI_INLINE(MCaptureOwnerEdge , SelectMgr_EntityOwner)
public:
	MCaptureOwnerEdge(TopoDS_Wire& edge , const Handle(AIS_InteractiveObject)& theObj , int thePriority = 0);

	virtual void HilightWithColor(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
								   const Handle(Prs3d_Drawer)& theStyle ,
								   const Standard_Integer theMode) override;

	virtual void Unhilight(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
							const Standard_Integer theMode) override;
protected:
	Handle(Prs3d_Presentation) myPrs;
	Handle(Prs3d_Drawer) myStyle;
	TopoDS_Wire myEdge;
};

// Presentation builders
class MAisObject0 : public AIS_InteractiveObject
{
	DEFINE_STANDARD_RTTI_INLINE(MAisObject0 , AIS_InteractiveObject)
public:
	enum MyDispMode {
		MyDispMode_Main = 0 , MyDispMode_Highlight = 1
	};

	MAisObject0(const TopoDS_Shape& shap);

	virtual void Compute(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
						  const Handle(Prs3d_Presentation)& thePrs ,
						  const Standard_Integer theMode) override;

	virtual void ComputeSelection(const Handle(SelectMgr_Selection)& theSel ,
								   const Standard_Integer theMode) override {
	}

	virtual bool AcceptDisplayMode(const Standard_Integer theMode) const override
	{
		return theMode == 0 || theMode == 1;
	}

	const TopoDS_Shape& Shape() const {
		return aShape;
	}

	void SetShape(const TopoDS_Shape& theShape)
	{
		aShape = theShape;
	}
private:
	TopoDS_Shape aShape;
};

// Primitive arrays
class MAisObject1 : public AIS_InteractiveObject
{
	DEFINE_STANDARD_RTTI_INLINE(MAisObject1 , AIS_InteractiveObject)
public:
	enum MyDispMode {
		MyDispMode_Main = 0 , MyDispMode_Highlight = 1
	};

	MAisObject1(const TopoDS_Shape& shap);

	virtual void Compute(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
						  const Handle(Prs3d_Presentation)& thePrs ,
						  const Standard_Integer theMode) override;

	virtual void ComputeSelection(const Handle(SelectMgr_Selection)& theSel ,
								   const Standard_Integer theMode) override {
	}

	virtual bool AcceptDisplayMode(const Standard_Integer theMode) const override
	{
		return theMode == 0 || theMode == 1;
	}

	const TopoDS_Shape& Shape() const {
		return aShape;
	}

	void SetShape(const TopoDS_Shape& theShape)
	{
		aShape = theShape;
	}
private:
	TopoDS_Shape aShape;
};

// Primitive aspects
class MAisObject2 : public AIS_InteractiveObject
{
	DEFINE_STANDARD_RTTI_INLINE(MAisObject2 , AIS_InteractiveObject)
public:
	enum MyDispMode {
		MyDispMode_Main = 0 , MyDispMode_Highlight = 1
	};

	MAisObject2(const TopoDS_Shape& shap);

	virtual void Compute(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
						  const Handle(Prs3d_Presentation)& thePrs ,
						  const Standard_Integer theMode) override;

	virtual void ComputeSelection(const Handle(SelectMgr_Selection)& theSel ,
								   const Standard_Integer theMode) override {
	}

	virtual bool AcceptDisplayMode(const Standard_Integer theMode) const override
	{
		return theMode == 0 || theMode == 1;
	}

	const TopoDS_Shape& Shape() const {
		return aShape;
	}

	void SetShape(const TopoDS_Shape& theShape)
	{
		aShape = theShape;
	}
private:
	TopoDS_Shape aShape;
};

//Quadric builders
class MAisObject3 : public AIS_InteractiveObject
{
	DEFINE_STANDARD_RTTI_INLINE(MAisObject3 , AIS_InteractiveObject)
public:
	enum MyDispMode {
		MyDispMode_Main = 0 , MyDispMode_Highlight = 1
	};

	MAisObject3(const TopoDS_Shape& shap);

	virtual void Compute(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
						  const Handle(Prs3d_Presentation)& thePrs ,
						  const Standard_Integer theMode) override;

	virtual void ComputeSelection(const Handle(SelectMgr_Selection)& theSel ,
								   const Standard_Integer theMode) override {
	}

	virtual bool AcceptDisplayMode(const Standard_Integer theMode) const override
	{
		return theMode == 0 || theMode == 1;
	}

	const TopoDS_Shape& Shape() const {
		return aShape;
	}

	void SetShape(const TopoDS_Shape& theShape)
	{
		aShape = theShape;
	}
private:
	TopoDS_Shape aShape;
};

// Computing selection
class MAisObject4 : public AIS_InteractiveObject
{
	DEFINE_STANDARD_RTTI_INLINE(MAisObject4 , AIS_InteractiveObject)
public:
	enum MyDispMode {
		MyDispMode_Main = 0 , MyDispMode_Highlight = 1
	};

	MAisObject4(const TopoDS_Shape& shap);

	virtual void Compute(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
						  const Handle(Prs3d_Presentation)& thePrs ,
						  const Standard_Integer theMode) override;

	virtual void ComputeSelection(const Handle(SelectMgr_Selection)& theSel ,
								   const Standard_Integer theMode) override;

	virtual bool AcceptDisplayMode(const Standard_Integer theMode) const override
	{
		return theMode == 0 || theMode == 1;
	}

	const TopoDS_Shape& Shape() const {
		return aShape;
	}

	void SetShape(const TopoDS_Shape& theShape)
	{
		aShape = theShape;
	}
private:
	TopoDS_Shape aShape;
};

// HighlightingSelectionOwner
class MAisObject5 : public AIS_InteractiveObject
{
	DEFINE_STANDARD_RTTI_INLINE(MAisObject5 , AIS_InteractiveObject)
public:
	enum MyDispMode {
		MyDispMode_Main = 0 , MyDispMode_Highlight = 1
	};

	MAisObject5(const TopoDS_Shape& shap);

	virtual void Compute(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
						  const Handle(Prs3d_Presentation)& thePrs ,
						  const Standard_Integer theMode) override;

	virtual void ComputeSelection(const Handle(SelectMgr_Selection)& theSel ,
								   const Standard_Integer theMode) override;

	virtual bool AcceptDisplayMode(const Standard_Integer theMode) const override
	{
		return theMode == 0 || theMode == 1;
	}

	const TopoDS_Shape& Shape() const {
		return aShape;
	}

	void SetShape(const TopoDS_Shape& theShape)
	{
		aShape = theShape;
	}
private:
	TopoDS_Shape aShape;
};

// add arrow
class MAisObject6 : public AIS_InteractiveObject
{
	DEFINE_STANDARD_RTTI_INLINE(MAisObject6 , AIS_InteractiveObject)
public:
	enum MyDispMode {
		MyDispMode_Main = 0 , MyDispMode_Highlight = 1
	};

	MAisObject6(const TopoDS_Shape& shap);

	virtual void Compute(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
						  const Handle(Prs3d_Presentation)& thePrs ,
						  const Standard_Integer theMode) override;

	virtual void ComputeSelection(const Handle(SelectMgr_Selection)& theSel ,
								   const Standard_Integer theMode) override;

	virtual bool AcceptDisplayMode(const Standard_Integer theMode) const override
	{
		return theMode == 0 || theMode == 1;
	}

	const TopoDS_Shape& Shape() const {
		return aShape;
	}

	void SetShape(const TopoDS_Shape& theShape)
	{
		aShape = theShape;
	}
private:
	TopoDS_Shape aShape;
};

// HLR
class myPk_IShape : public AIS_InteractiveObject
{
	DEFINE_STANDARD_RTTI_INLINE(myPk_IShape , AIS_InteractiveObject)
public:

	myPk_IShape(const TopoDS_Shape& theShape , PrsMgr_TypeOfPresentation3d theType);

	virtual void Compute(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
						  const Handle(Prs3d_Presentation)& thePrs ,
						  const Standard_Integer theMode) override;

	virtual void computeHLR(const Handle(Graphic3d_Camera)& theProjector ,
		const Handle(TopLoc_Datum3D)& theTrsf ,
		const Handle(Prs3d_Presentation)& thePrs) override;

	virtual void ComputeSelection(const Handle(SelectMgr_Selection)& theSel ,
							   const Standard_Integer theMode) override {
	}

	virtual bool AcceptDisplayMode(const Standard_Integer theMode) const override
	{
		return theMode == 0 || theMode == 1;
	}

	virtual void SetColor(const Quantity_Color& theColor) override;

private:
	TopoDS_Shape myShape;
};

// Primitive arrays
class MAisObject7 : public AIS_InteractiveObject
{
	DEFINE_STANDARD_RTTI_INLINE(MAisObject7 , AIS_InteractiveObject)
public:
	enum MDispMode {
		MDispMode_WireFrame ,
		MDispMode_Shaded
	};

	MAisObject7();

	virtual void Compute(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
						  const Handle(Prs3d_Presentation)& thePrs ,
						  const Standard_Integer theMode) override;

	virtual void ComputeSelection(const Handle(SelectMgr_Selection)& theSel ,
								   const Standard_Integer theMode) override;

	virtual bool AcceptDisplayMode(const Standard_Integer theMode) const override
	{
		return theMode == MDispMode_WireFrame || theMode == MDispMode_Shaded;
	}

private:

};

// Text primitive
class MAisObject8 : public AIS_InteractiveObject
{
	DEFINE_STANDARD_RTTI_INLINE(MAisObject8 , AIS_InteractiveObject)
public:
	enum MDispMode {
		MDispMode_WireFrame ,
		MDispMode_Shaded
	};

	MAisObject8() {};

	virtual void Compute(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
						  const Handle(Prs3d_Presentation)& thePrs ,
						  const Standard_Integer theMode) override;

	virtual void ComputeSelection(const Handle(SelectMgr_Selection)& theSel ,
								   const Standard_Integer theMode) override {
	};

	virtual bool AcceptDisplayMode(const Standard_Integer theMode) const override
	{
		return theMode == MDispMode_WireFrame || theMode == MDispMode_Shaded;
	}

private:
	
};


// Bounding boxes
class MAisObject9 : public AIS_InteractiveObject
{
	DEFINE_STANDARD_RTTI_INLINE(MAisObject9 , AIS_InteractiveObject)
public:
	enum MDispMode {
		MDispMode_WireFrame ,
		MDispMode_Shaded
	};

	MAisObject9(TopoDS_Shape& shap);

	virtual void Compute(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
						  const Handle(Prs3d_Presentation)& thePrs ,
						  const Standard_Integer theMode) override;

	virtual void ComputeSelection(const Handle(SelectMgr_Selection)& theSel ,
								   const Standard_Integer theMode) override;

	virtual bool AcceptDisplayMode(const Standard_Integer theMode) const override
	{
		return theMode == MDispMode_WireFrame || theMode == MDispMode_Shaded;
	}

private:
	TopoDS_Shape myShape;
};

// HighlightingSelectionOwner
class MAisOwner5 : public SelectMgr_EntityOwner
{
	DEFINE_STANDARD_RTTI_INLINE(MAisOwner5 , SelectMgr_EntityOwner)
public:
	MAisOwner5(const Handle(MAisObject5)& theObj , int thePriority = 0)
		: SelectMgr_EntityOwner(theObj , thePriority) {
	}

	virtual void HilightWithColor(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
								   const Handle(Prs3d_Drawer)& theStyle ,
								   const Standard_Integer theMode) override;

	virtual void Unhilight(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
							const Standard_Integer theMode) override;
protected:
	Handle(Prs3d_Presentation) myPrs;
};

// add arrow
class MAisOwner6 : public SelectMgr_EntityOwner
{
	DEFINE_STANDARD_RTTI_INLINE(MAisOwner6 , SelectMgr_EntityOwner)
public:
	MAisOwner6(const Handle(MAisObject6)& theObj , int thePriority = 0)
		: SelectMgr_EntityOwner(theObj , thePriority) {
	}

	virtual void HilightWithColor(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
								   const Handle(Prs3d_Drawer)& theStyle ,
								   const Standard_Integer theMode) override;

	virtual void Unhilight(const Handle(PrsMgr_PresentationManager)& thePrsMgr ,
							const Standard_Integer theMode) override;
	virtual bool IsForcedHilight() const override {
		return true;
	}
protected:
	Handle(Prs3d_Presentation) myPrs;
};
